package network

import (
	"net"
	"sync"

	"gitee.com/terender/sfw/rlog"
)

//Server : 管理服务器的网络层
type Server struct {
	sync.RWMutex
	listener       net.Listener //监听socket
	connections    map[string]*Connection
	routines       map[int32]Routine
	defaultRoutine Routine
	parties        map[string]*Party
	OnNewConn      func(*Connection)
	OnRecvMessage  func(*Context)
	OnRespMessage  func(*Context, *Message)

	ReadBuffSize       int // 与客户端的通信的读缓冲区初始长度
	ReadBuffSizeMax    int // 与客户端的通信的读缓冲区最大长度
	ReadTimeoutInitial int // TCP连接建立后首次read的超时时间
	ReadTimeout        int // read超时时间
}

// NewServer 构造函数，创建一个新的 Server 对象
func NewServer() *Server {
	return &Server{
		routines:           make(map[int32]Routine),
		parties:            make(map[string]*Party),
		connections:        make(map[string]*Connection),
		ReadBuffSize:       1024,
		ReadBuffSizeMax:    8 * 1024 * 1024,
		ReadTimeoutInitial: 10,
		ReadTimeout:        90,
	}
}

// Party 创建或者返回一个指定名称的协议组
func (s *Server) Party(name string) *Party {
	if s.parties == nil {
		s.parties = make(map[string]*Party)
	}
	p, ok := s.parties[name]
	if ok {
		return p
	}
	p = &Party{name: name, s: s, routines: make(map[int32]Routine)}
	s.parties[name] = p
	return p
}

// RegisterProc 向TCP服务的默认消息组注册消息处理路由，默认消息组名字为空
func (s *Server) RegisterProc(id int32, proc Proc) { s.Party(``).RegisterProc(id, proc) }

// DefaultProc 向TCP服务注册默认消息处理路由，不能在路由表中查到的消息ID会交给默认消息路由处理
func (s *Server) DefaultProc(proc Proc) {
	s.defaultRoutine = Routine{proc: proc, p: s.Party(`__internal__`)}
}

// findMessageRoute 查找网络消息处理器
func (s *Server) findMessageRoute(msgID int32) (Routine, bool) {
	r, ok := s.routines[msgID]
	if ok {
		return r, ok
	}
	return s.defaultRoutine, false
}

// Start : Server 启动，一旦有新连接加入客户端管理器里
func (s *Server) Start(ip string) error {
	var err error
	s.listener, err = net.Listen("tcp", ip)
	if err != nil {
		rlog.Errorf("listen err:%s", err.Error())
		return err
	}

	for {
		conn, err := s.listener.Accept()
		if err != nil {
			rlog.Errorf("accept err(before): %s ", err.Error())
			if ne, ok := err.(net.Error); ok && ne.Temporary() {
				rlog.Infof("accept net error: %+v", ne)
				continue
			}
			rlog.Errorf("accept error(after): %+v", err.Error())
			return err
		}
		//log.Println(conn.RemoteAddr().String())
		connection := newConnection(s, conn.(*net.TCPConn))
		s.addConnection(connection)
		if s.OnNewConn != nil {
			s.OnNewConn(connection)
		}
	}
}

//Shutdown 服务关闭
func (s *Server) Shutdown() {
	if s.listener != nil {
		err := s.listener.Close()
		if err != nil {
			rlog.Errorf("listener close err: %s", err.Error())
		}
	}
}

// CloseConnections 关闭服务器已建立的全部连接
func (s *Server) CloseConnections() bool {
	count := 0
	quits := make([]<-chan bool, 0)
	s.RLock()
	for _, value := range s.connections {
		count++
		//rlog.Infof(`关闭连接 %v `, key)
		quits = append(quits, value.Close())
		//return true
	}
	s.RUnlock()
	for _, c := range quits {
		<-c
		count--
		//log.Println(utils.FuncName(), `: 收到一个conn可以关闭的信号 count-- [`, count, `]`)
		if count == 0 {
			rlog.Infof(`已关闭全部TCP连接`)
			return true
		}
	}
	s.connections = nil
	return false
}

func (s *Server) addConnection(conn *Connection) {
	s.Lock()
	defer s.Unlock()
	s.connections[conn.conn.RemoteAddr().String()] = conn
}

func (s *Server) removeConnection(addr string) {
	s.Lock()
	defer s.Unlock()
	delete(s.connections, addr)
}

// ConnectionCout 当前连接数量
func (s *Server) ConnectionCout() int {
	s.RLock()
	defer s.RUnlock()
	return len(s.connections)
}
